import 'dart:math';
import 'dart:ui';

import 'package:flame/flame.dart';
import 'package:flame/game.dart';
import 'package:flame/gestures.dart';
import 'package:flutter/material.dart';
import 'package:hello_flutter/demo/game/components/enemy.dart';
import 'package:hello_flutter/demo/game/components/heath_bar.dart';
import 'package:hello_flutter/demo/game/components/player.dart';
import 'package:hello_flutter/demo/game/components/score_text.dart';
import 'package:hello_flutter/demo/game/components/start_text.dart';
import 'package:hello_flutter/demo/game/enemy_spawner.dart';
import 'package:hello_flutter/demo/game/game_state.dart';
import 'package:shared_preferences/shared_preferences.dart';

import 'components/high_score_text.dart';

class GameController extends Game with TapDetector {
  Random random; // 随机生成
  Size screenSize; // 屏幕尺寸
  double tileSize; // 瓦片单位尺寸
  Player player; // 角色
  List<Enemy> enemies; // 敌人
  HeathBar heathBar; // 血条
  EnemySpawner spawner; // 敌人产生器
  int score; // 得分
  ScoreTxT scoreTxT; // 记分文本组件
  HighScoreTxT highScoreTxT; // 最高分文本组件
  StartTxT startTxT; // 开始按钮🔘
  final SharedPreferences storage;
  GameState state; // 游戏状态

  GameController(this.storage) {
    initialize();
  }

  void initialize() async {
    resize(await Flame.util.initialDimensions());
    state = GameState.menu;
    player = Player(this);
    heathBar = HeathBar(this);
    enemies = List<Enemy>();
    spawner = EnemySpawner(this);
    random = Random();
    spawnEnemy();
    score = 0;
    scoreTxT = ScoreTxT(this);
    highScoreTxT = HighScoreTxT(this);
    startTxT = StartTxT(this);
  }

  @override
  void render(Canvas canvas) {
    final background = Rect.fromLTWH(0, 0, screenSize.width, screenSize.height);
    final bgPaint = Paint()..color = Colors.white; // 颜料🎨
    canvas.drawRect(background, bgPaint);
    // 渲染出画面(绘制组件)
    player.render(canvas);
    switch (state) {
      case GameState.menu:
        highScoreTxT.render(canvas);
        startTxT.render(canvas);
        break;
      case GameState.play:
        enemies.forEach((enemy) => enemy.render(canvas));
        heathBar.render(canvas);
        scoreTxT.render(canvas);
        break;
    }
  }

  @override
  void update(double time) {
    switch (state) {
      case GameState.menu:
        highScoreTxT.update(time);
        startTxT.update(time);
        break;
      case GameState.play:
        spawner.update(time);
        enemies.forEach((enemy) => enemy.update(time));
        enemies.removeWhere((enemy) => enemy.isDead);
        player.update(time);
        heathBar.update(time);
        scoreTxT.update(time);
        break;
    }
  }

  @override
  void resize(Size size) {
    screenSize = size;
    tileSize = screenSize.width / 10;
    super.resize(size);
  }

  @override
  void onTapDown(TapDownDetails details) {
    switch (state) {
      case GameState.menu:
        state = GameState.play;
        break;
      case GameState.play:
        enemies.forEach((enemy) {
          if (enemy.enemyRect.contains(details.globalPosition)) {
            enemy.onTapDown(details);
          }
        });
        break;
    }
    super.onTapDown(details);
  }

  void spawnEnemy() {
    double x, y;
    switch (random.nextInt(4)) {
      case 0: // 上
        x = random.nextDouble() * screenSize.width;
        y = -tileSize * 2.5;
        break;
      case 1: // 右
        x = screenSize.width + tileSize * 2.5;
        y = random.nextDouble() * screenSize.height;
        break;
      case 2: // 下
        x = random.nextDouble() * screenSize.width;
        y = screenSize.height + tileSize * 2.5;
        break;
      case 3: // 左
        x = -tileSize * 2.5;
        y = random.nextDouble() * screenSize.height;
        break;
    }
    enemies.add(Enemy(this, x, y));
  }
}
